<template>
  <div class="image-upload-container">
    <!-- 图片列表 -->
    <div class="image-list">
      <div 
        v-for="(item, index) in fileList" 
        :key="index"
        class="image-item"
        :class="{ 'uploading': item.uploading }"
      >
        <div class="image-wrapper">
          <img :src="item.url" alt="" class="uploaded-image" />
          <div class="image-overlay">
            <i class="el-icon-zoom-in" @click="previewImage(item.url)"></i>
            <i v-if="!disabled" class="el-icon-delete" @click="removeFile(index)"></i>
          </div>
          <!-- 上传进度遮罩 -->
          <div v-if="item.uploading" class="upload-mask">
            <el-progress 
              type="circle" 
              :percentage="item.progress || 0"
              :width="50"
            ></el-progress>
          </div>
        </div>
      </div>
      
      <!-- 上传区域 -->
      <div 
        v-if="!disabled && fileList.length < maxCount"
        class="upload-area"
      >
        <el-upload
          ref="upload"
          :action="uploadUrl"
          :headers="uploadHeaders"
          :before-upload="beforeUpload"
          :on-progress="onProgress"
          :on-success="onSuccess"
          :on-error="onError"
          :show-file-list="false"
          :accept="acceptTypes"
          class="image-uploader"
        >
          <div class="upload-trigger">
            <i class="el-icon-plus"></i>
            <div class="upload-text">上传图片</div>
          </div>
        </el-upload>
      </div>
    </div>

    <!-- 图片预览对话框 -->
    <el-dialog 
      :visible.sync="previewVisible" 
      title="图片预览"
      width="60%"
      center
    >
      <img :src="previewUrl" alt="" style="width: 100%; height: auto;" />
    </el-dialog>

    <!-- 配置说明 -->
    <div class="upload-tips" v-if="showTips && !disabled">
      <p>支持 {{ acceptTypes }} 格式，单个文件不超过 {{ maxSize }}MB，最多上传 {{ maxCount }} 个文件</p>
    </div>
  </div>
</template>

<script>
import request from '@/utils/request'
import { getToken } from '@/utils/auth'

export default {
  name: 'ImageUpload',
  props: {
    // v-model 绑定的文件数组或JSON字符串
    value: {
      type: [Array, String],
      default: () => []
    },
    // 最大上传数量
    maxCount: {
      type: Number,
      default: 50
    },
    // 最大文件大小(MB)
    maxSize: {
      type: Number,
      default: 50
    },
    // 接受的文件类型
    acceptTypes: {
      type: String,
      default: '.jpg,.jpeg,.png,.gif'
    },
    // 是否显示提示信息
    showTips: {
      type: Boolean,
      default: true
    },
    // 是否禁用上传功能（只显示预览）
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      fileList: [],
      uploadUrl: 'http://125.39.77.18:9021/mall-admin/fileUpload/upload',
      previewVisible: false,
      previewUrl: '',
      uploadingCount: 0 // 正在上传的文件数量
    }
  },
  computed: {
    uploadHeaders() {
      return {
        'Authorization': 'Bearer ' + getToken()
      }
    }
  },
  watch: {
    value: {
      handler(newVal) {
        // 如果是字符串，尝试解析为数组
        let parsedValue = []
        if (typeof newVal === 'string') {
          try {
            parsedValue = newVal ? JSON.parse(newVal) : []
          } catch (error) {
            console.warn('ImageUpload: 无法解析value字符串为JSON数组:', newVal, error)
            parsedValue = []
          }
        } else if (Array.isArray(newVal)) {
          parsedValue = newVal
        }

        this.fileList = parsedValue.map(item => ({
          ...item,
          uploading: false,
          progress: 100
        }))
      },
      immediate: true,
      deep: true
    },
    uploadingCount(newVal) {
      // 当有文件正在上传时，给容器添加特殊class
      const container = this.$el
      if (newVal > 0) {
        container.classList.add('files-uploading')
      } else {
        container.classList.remove('files-uploading')
      }
    }
  },
  methods: {
    // 上传前校验
    beforeUpload(file) {
      // 检查文件类型
      const isValidType = this.checkFileType(file)
      if (!isValidType) {
        this.$message.error(`只能上传 ${this.acceptTypes} 格式的图片!`)
        return false
      }

      // 检查文件大小
      const isValidSize = file.size / 1024 / 1024 < this.maxSize
      if (!isValidSize) {
        this.$message.error(`上传图片大小不能超过 ${this.maxSize}MB!`)
        return false
      }

      // 检查数量限制
      if (this.fileList.length >= this.maxCount) {
        this.$message.error(`最多只能上传 ${this.maxCount} 个文件!`)
        return false
      }

      // 添加到文件列表，显示上传状态
      const tempItem = {
        name: file.name,
        size: file.size,
        type: file.type,
        url: URL.createObjectURL(file), // 临时预览URL
        uploading: true,
        progress: 0,
        tempFile: true
      }
      this.fileList.push(tempItem)
      this.uploadingCount++

      return true
    },

    // 上传进度
    onProgress(event, file) {
      const targetIndex = this.fileList.findIndex(item => item.tempFile && item.name === file.name)
      if (targetIndex !== -1) {
        this.fileList[targetIndex].progress = Math.round(event.percent)
        this.$forceUpdate()
      }
    },

    // 上传成功
    onSuccess(response, file) {
      const targetIndex = this.fileList.findIndex(item => item.tempFile && item.name === file.name)
      if (targetIndex !== -1) {
        // 释放临时URL
        URL.revokeObjectURL(this.fileList[targetIndex].url)
        
        // 更新文件信息
        this.fileList[targetIndex] = {
          name: response.data.name,
          size: response.data.fileSize,
          type: response.data.type,
          url: response.data.url,
          uploading: false,
          progress: 100,
          tempFile: false
        }
        
        this.uploadingCount--
        this.emitChange()
        this.$message.success('上传成功!')
      }
    },

    // 上传失败
    onError(error, file) {
      const targetIndex = this.fileList.findIndex(item => item.tempFile && item.name === file.name)
      if (targetIndex !== -1) {
        // 释放临时URL
        URL.revokeObjectURL(this.fileList[targetIndex].url)
        // 移除失败的文件
        this.fileList.splice(targetIndex, 1)
        this.uploadingCount--
      }
      this.$message.error('上传失败!')
    },

    // 移除文件
    removeFile(index) {
      const item = this.fileList[index]
      if (item.tempFile && item.url.startsWith('blob:')) {
        URL.revokeObjectURL(item.url)
      }
      if (item.uploading) {
        this.uploadingCount--
      }
      this.fileList.splice(index, 1)
      this.emitChange()
    },

    // 预览图片
    previewImage(url) {
      this.previewUrl = url
      this.previewVisible = true
    },

    // 检查文件类型
    checkFileType(file) {
      const acceptedTypes = this.acceptTypes.split(',').map(type => type.trim().toLowerCase())
      const fileName = file.name.toLowerCase()
      return acceptedTypes.some(type => {
        if (type.startsWith('.')) {
          return fileName.endsWith(type)
        }
        return file.type.includes(type)
      })
    },

    // 触发v-model更新
    emitChange() {
      const result = this.fileList
        .filter(item => !item.uploading && !item.tempFile)
        .map(item => ({
          name: item.name,
          size: item.size,
          type: item.type,
          url: item.url
        }))
      
      // 根据原始value类型决定输出格式
      if (typeof this.value === 'string') {
        this.$emit('input', JSON.stringify(result))
      } else {
        this.$emit('input', result)
      }
    }
  },

  beforeDestroy() {
    // 清理临时URL
    this.fileList.forEach(item => {
      if (item.tempFile && item.url.startsWith('blob:')) {
        URL.revokeObjectURL(item.url)
      }
    })
  }
}
</script>

<style scoped>
.image-upload-container {
  width: 100%;
}

.image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.image-item {
  position: relative;
  width: 150px;
  height: 150px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  overflow: hidden;
  transition: all 0.3s;
}

.image-item:hover {
  border-color: #409eff;
}

.image-item.uploading {
  border-color: #409eff;
  background-color: #f5f7fa;
}

.image-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
}

.uploaded-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  opacity: 0;
  transition: opacity 0.3s;
}

.image-item:hover .image-overlay {
  opacity: 1;
}

.image-overlay i {
  color: white;
  font-size: 18px;
  cursor: pointer;
  padding: 5px;
  border-radius: 3px;
  transition: background-color 0.3s;
}

.image-overlay i:hover {
  background-color: rgba(255, 255, 255, 0.2);
}

.upload-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
}

.upload-area {
  width: 150px;
  height: 150px;
}

.image-uploader {
  width: 100%;
  height: 100%;
}

.image-uploader >>> .el-upload {
  width: 100%;
  height: 100%;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: all 0.3s;
}

.image-uploader >>> .el-upload:hover {
  border-color: #409eff;
}

.upload-trigger {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #8c939d;
}

.upload-trigger .el-icon-plus {
  font-size: 28px;
  margin-bottom: 5px;
}

.upload-text {
  font-size: 14px;
}

.upload-tips {
  margin-top: 10px;
  color: #999;
  font-size: 12px;
}

.upload-tips p {
  margin: 0;
}

/* 全局class，用于检测是否有文件正在上传 */
.files-uploading {
  position: relative;
}
</style>